//给你单链表的头指针 head 和两个整数 left 和 right ，其中 left <= right 。请你反转从位置 left 到位置 right 的链
//表节点，返回 反转后的链表 。
//
// 
//
// 示例 1： 
// 
// 
//输入：head = [1,2,3,4,5], left = 2, right = 4
//输出：[1,4,3,2,5]
// 
//
// 示例 2： 
//
// 
//输入：head = [5], left = 1, right = 1
//输出：[5]
// 
//
// 
//
// 提示： 
//
// 
// 链表中节点数目为 n 
// 1 <= n <= 500 
// -500 <= Node.val <= 500 
// 1 <= left <= right <= n 
// 
//
// 
//
// 进阶： 你可以使用一趟扫描完成反转吗？ 
//
// Related Topics 链表 👍 1455 👎 0


package leetcode.editor.cn;
public class ReverseLinkedListIi{
  public static void main(String[] args) {
       Solution solution = new ReverseLinkedListIi().new Solution();
      ReverseLinkedListIi.ListNode listNode = solution.reverseBetween(new ReverseLinkedListIi.ListNode(1, new ReverseLinkedListIi.ListNode(2, new ReverseLinkedListIi.ListNode(3, new ReverseLinkedListIi.ListNode(4, new ReverseLinkedListIi.ListNode(5))))), 2, 4);
      while (listNode != null && listNode.val != -1){
          System.out.println(listNode.val);
          listNode = listNode.next;
      }
  }
  //leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    public ListNode reverseBetween(ListNode head, int left, int right) {
        //设置dummyNode
        ListNode dummyNode = new ListNode(-1, head);
        ListNode pre = dummyNode;
        for (int i=0; i <left-1; i++) {
            //pre：永远指向待反转区域的第一个节点 left 的前一个节点，在循环过程中不变。
            pre = pre.next;
        }
        //curr：指向待反转区域的第一个节点 left；
        ListNode cur = pre.next;
        ListNode next = null;
        //头插法
        for (int i=0; i<right-left; i++) {
            //next：永远指向 curr 的下一个节点，循环过程中，curr 变化以后 next 会变化；
            next = cur.next;
            //操作 ①：把 curr 的下一个节点指向 next 的下一个节点；
            cur.next = cur.next.next;
            //操作 ②：把 next 的下一个节点指向 pre 的下一个节点；
            next.next = pre.next;
            //操作 ③：把 pre 的下一个节点指向 next
            pre.next = next;
        }
        return dummyNode.next;
    }
}
//leetcode submit region end(Prohibit modification and deletion)
/**
 * Definition for singly-linked list.
 */
public static class ListNode {
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) { this.val = val; }
    ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
}